package com.web_bloks.document.client;

import com.google.gwt.core.client.GWT;

/**
 * Don't forget to CONFIGURE!
 * 
 * @author Jean-Lou Dupont
 *
 */
public class Namespace {

	final static String thisClass = "com.web_bloks.document.client.Namespace";
	
	public enum Code {
		WILD, NORMAL
	}
	
	Code   cName = Code.NORMAL;
	String domainid = null;
	String name = null;
	
	static Namespaces namespaces = null;
	
	/*===================================================================
	 * CONSTRUCTORS 
	 ===================================================================*/
	protected Namespace() {
		super();
	}
	
	protected Namespace(String domainid, String name) {
		super();
		this.domainid = new String(domainid);
		this.name = new String(name);
	}
	
	public void setDomainId(String did) {
		this.domainid = did;
	}
	public void setName(String name) {
		this.name = name;
	}
	public void setWild() {
		this.cName = Code.WILD; 
	}
	/*===================================================================
	 * CONFIGURATION 
	 ===================================================================*/
	public static void setNamespaces(Namespaces nss) {
		namespaces = nss;
	}
	
	/*===================================================================
	 * BUILDERS 
	 ===================================================================*/
	/**
	 * Creates a corresponding 'raw' namespace from a 'base' one
	 * @param base namespace
	 * @return raw namespace
	 */
	public static Namespace createRaw(Namespace ns) throws NamespaceException {

		if (null == ns)
			throw new RuntimeException( thisClass+ ".createRaw: ns can't be null" );
		
		//Logger.logInfo(thisClass+".createRaw, name["+ns.getName()+"]");
			
		String domainid = namespaces.lookup(ns.getName());
		if ( null == domainid ) {
			//Logger.logInfo(thisClass+".createRaw: can't find in 'base'");
			throw new NamespaceException(thisClass+".createRaw: can't find domain");
		}
		
		String name = namespaces.getRawFromDomainId(domainid);
		
		return build( domainid, name );
	}

	public static Namespace createBase(Namespace ns) throws NamespaceException {

		if (null == ns)
			throw new RuntimeException( thisClass+ ".createBase: ns can't be null" );
		
		//Logger.logInfo(thisClass+".createBase, name["+ns.getName()+"]");

		String domainid = namespaces.lookup(ns.getName());
		if ( null == domainid ) {
			//Logger.logInfo(thisClass+".createBase: can't find in 'raw'");
			throw new NamespaceException(thisClass+".createBase: can't find domain");
		}
		
		String name = namespaces.getBaseFromDomainId(domainid);
		
		return build( domainid, name );
	}

	public static Namespace create(String name) throws NamespaceException {
		
		if (null == name)
			throw new RuntimeException( thisClass+ ".create: name can't be null" );

		//Logger.logInfo(thisClass+".create");
		String id = namespaces.lookup(name);
		if ( null == id )
			throw new NamespaceException(thisClass+".create: domain not found");
		
		return build( id, name );
	}
	/**
	 * creates a wildcard namespace
	 * 
	 * @return Namespace
	 */
	public static Namespace createWild() {
		return build( "*", "*" );
	}
	
	private static Namespace build(String domainid, String name) {
		
		Namespace nsi = (Namespace) GWT.create(Namespace.class);
		nsi.setDomainId(domainid);
		nsi.setName(name);
		
		if (isWildComponent( name ))
			nsi.setWild();
		
		return nsi;
	}
	
	/*===================================================================
	 * API 
	 ===================================================================*/
	public boolean isNormal() {
		return cName == Code.NORMAL;
	}
	public boolean isWild() {
		return cName == Code.WILD;
	}
	public String toString() {
		return name;
	}
	public String getName() {
		return name;
	}
	public String getDomainId() {
		return domainid;
	}
	public boolean isRaw() {
		return (namespaces.lookupInRaw(this.name) != null);
	}
	public boolean isBase() {
		return (namespaces.lookupInBase(this.name) != null);
	}
	/*===================================================================
	 * WILD related 
	 ===================================================================*/
	protected static boolean isWildComponent(String c) {
		if (null == c)
			return false;
	
		return ( "*" == c );
	}
	
	/*===================================================================
	 * Overrides
	 ===================================================================*/
	/*
		Code   cName = Code.NORMAL;
		String domainid = null;
		String name = null;
	 */
	public boolean equals(Object n) {
		
		if (!( n instanceof Namespace ))
			throw new RuntimeException(this.getClass()+".equals: unsupported comparison");
		
		// shortcut
		Namespace nc = (Namespace) n;
	
		if ( nc.cName    != this.cName    ) return false;
		if ( nc.domainid != this.domainid ) return false;
		if ( nc.name     != this.name     ) return false;
		
		return true;
	}

}//END